<!DOCTYPE html>
<html lang="fr">

<head>
	<meta charset="utf-8">
	<base href="../../../" />
	<script src="page.js"></script>
	<link type="text/css" rel="stylesheet" href="page.css" />
</head>

<body>
	<h1>Supprimer un objet ([name])</h1>

	<p>
		Un des aspects importants dans l'amélioration des performances et qui permet d'éviter les fuites de mémoire dans votre application est la suppression des entités non-utilisées de la librairie.
		Dès que vous créez une instance d'un type *three.js*, vous allouez une certaine quantité de mémoire. Toutefois, *three.js* crée pour certains objets
		comme les formes ou les matériaux, des entités WebGL associées comme des buffers ou des programmes de shaders qui sont nécessaires au rendu. Il est important de
		souligner que ces objets ne sont pas automatiquement débarassés. Au contraire, l'application doit utiliser une API particulière pour libérer ce genre de ressources.
		Ce guide vous fournit une brève vue d'ensemble du fonctionnement de cette API et des objets considérés comme pertinents dans ce contexte.
	</p>

	<h2>Formes</h2>

	<p>
		Une forme représente généralement des informations concernant des sommets présentés comme un ensemble d'attributs. *three.js* crée en interne un objet de type [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLBuffer WebGLBuffer]
		pour chaque attribut. Ces entités sont supprimées uniquement si vous appelez [page:BufferGeometry.dispose](). Si une forme devient obsolète dans votre application,
		exécutez cette méthode pour libérer toutes les ressources associées.
	</p>

	<h2>Matériaux</h2>

	<p>
		Un matériau définit comment un objet est rendu. *three.js* utilise les informations de la définition du matériau pour construire un programme de shader pour le rendu.
		Les programmes de shader peuvent être supprimés seulement si leur matériau respectif est supprimé. Dans un souci de performances, *three.js* essaye de réutiliser des
		programmes de shaders existants si possible. Donc un programme de shader est supprimé uniquement si tous les matériaux associés sont supprimés. Vous pouvez indiquer la suppression d'un matériau en 
		exécutant [page:Material.dispose]().
	</p>

	<h2>Textures</h2>

	<p>
		La suppression d'un matériau n'a aucun effet sur les textures. Elles sont gérées séparément étant donné qu'une seule texture peut-être utilisée par plusieurs matériaux au même moment.
		Chaque fois que vous créez une instance de [page:Texture], three.js crée en interne une instance de [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture].
		Comme les buffers, cet objet ne peut-être supprimé qu'en appelant [page:Texture.dispose]().
	</p>

	<p>
		Si vous utilisez une `ImageBitmap` comme source de données pour une texture, vous devez appeler [link:https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap/close ImageBitmap.close]() au niveau de l'application pour libérer toutes les ressources côté processeur.
		Un appel automatisé de `ImageBitmap.close()` dans [page:Texture.dispose]() n'est pas possible, étant donné que le bitmap devient inutilisable, et que le moteur n'a aucun moyen de savoir si l'image bitmap est utilisée ailleurs.
	</p>

	<h2>Cibles de rendu</h2>

	<p>
		Les objets de type [page:WebGLRenderTarget] n'allouent pas qu'une instance de [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLTexture WebGLTexture] mais également
		[link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLFramebuffer WebGLFramebuffer]s et [link:https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderbuffer WebGLRenderbuffer]s
		pour réaliser des rendus customisés. Ces objets ne sont désalloués qu'en exécutant [page:WebGLRenderTarget.dispose]().
	</p>

	<h2>Divers</h2>

	<p>
		Il y a d'autres classes du dossier example comme controls ou les effets de post processings qui fournissent la méthode `dispose()` pour retirer des event listeners internes
		ou des cibles de rendu. En général, il est recommandé de jeter un coup d'oeil à l'API ou à la documentation d'une classe en cherchant un `dispose()`. Si il existe, vous devez l'utiliser pour faire votre petit ménage après utilisation.
	</p>

	<h2>FAQ</h2>

	<h3>Pourquoi *three.js* ne peut pas supprimer automatiquement les objets?</h3>

	<p>
		Cette question a été posée énormément de fois par la communauté, il est donc important de clarifier ce sujet. Le fait est que *three.js* ne connaît pas la durée de vie ou la portée des
		entités comme les formes ou les matériaux créés par les utilisateurs. Il en va de la responsabilité de l'application. Par exemple, si un matériau n'est pas utilisé pour le rendu pour l'instant,
		il peut être nécessaire pour le prochain frame. Donc si l'application décide qu'un certain objet peut-être supprimé, elle doit en notifier le moteur en appelant la méthode
		`dispose()`.
	</p>

	<h3>Retirer un mesh de la scène supprime également sa forme et son matériau?</h3>

	<p>
		Non, vous devez explicitement supprimer la forme et le matériau via *dispose()*. Gardez à l'esprit que les formes et matériaux peuvent être partagés entre plusieurs objets 3D comme les meshes.
	</p>

	<h3>Est-ce que *three.js* fournit des informations à propos des objets en cache?</h3>

	<p>
		Oui. Il est possible d'interroger [page:WebGLRenderer.info], qui est une propriété spéciale du moteur de rendu avec une série d'informations et de statistiques à propos de l'usage graphique
		et du proccessus de rendu. Entre autres, cela peut vous donner des informations comme le nombre de textures, de formes et de programmes de shaders stockés en interne. Si vous remarquez des problèmes de performance
		dans votre application, une bonne idée serait de débugger cette propriété pour facilement identifier une fuite de mémoire.
	</p>

	<h3>Que se passe t-il quand on appelle `dispose()` sur une texture mais que l'image n'est pas encore chargée?</h3>

	<p>
		Des ressources internes sont allouées pour une texture uniquement si l'image est entièrement chargée. Si vous supprimez une texture avant que l'image soit chargée,
		rien ne se produit. Aucune ressource n'était allouée il n'y a donc rien à libérer.
	</p>

	<h3>Que se passe t-il quand on appelle `dispose()` puis qu'on utilise l'objet plus tard?</h3>

	<p>
		Les ressources internes libérées sont réallouées par le moteur. Il n'y aura donc pas d'erreur d'exécution mais vous remarquerez probablement un impact négatif sur les performances au frame actuel,
		particulièrement quand le programme de shaders doit-être compilé.
	</p>

	<h3>Comment gérer les objets *three.js* dans mon application? Quand dois-je supprimer les objets?</h3>

	<p>
		En général, il n'y a pas de recommandation universelle pour cette question. Savoir si l'utilisation de `dispose()` est appropriée dépend grandement des cas d'utilisation. Il est important de souligner qu'il
		n'est pas nécessaire de toujours se débarasser des objets. Un bon exemple serait un jeu avec de multiple niveaux. Le bon moment pour supprimer les objets serait à un changement
		de niveau. L'application devrait traverser les anciennes scènes et supprimer tous les matériaux, les formes et les textures obsolètes. Comme mentionné dans la section précédente, supprimer des
		objets toujours utilisés ne produit pas d'erreur d'exécution. La pire chose qui pourrait se produire serait une baisse de la performance à un seul frame.
	</p>

	<h2>Exemples qui montrent l'utilisation de dispose()</h2>

	<p>
		[example:webgl_test_memory WebGL / test / memory]<br />
		[example:webgl_test_memory2 WebGL / test / memory2]<br />
	</p>

</body>

</html>
